﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Activity.DBHelper
{
    public class IListDataSet
    {
        /// <summary>
        /// 集合装换DataSet
        /// </summary>
        /// <param name="list">集合</param>
        /// <returns></returns>
        /// 2008-08-01 22:08 HPDV2806
        public static DataSet DataSetToDataSet(IList p_List)

        {

            DataSet result = new DataSet();

            DataTable _DataTable = new DataTable();

            if (p_List.Count > 0)

            {

                PropertyInfo[] propertys = p_List[0].GetType().GetProperties();

                foreach (PropertyInfo pi in propertys)

                {

                    _DataTable.Columns.Add(pi.Name, pi.PropertyType);

                }



                for (int i = 0; i < p_List.Count; i++)

                {

                    ArrayList tempList = new ArrayList();

                    foreach (PropertyInfo pi in propertys)

                    {

                        object obj = pi.GetValue(p_List[i], null);

                        tempList.Add(obj);

                    }

                    object[] array = tempList.ToArray();

                    _DataTable.LoadDataRow(array, true);

                }

            }

            result.Tables.Add(_DataTable);

            return result;

        }

        /// <summary>
        /// 泛型集合转换DataSet
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list">泛型集合</param>
        /// <returns></returns>
        /// 2008-08-01 22:43 HPDV2806
        public static DataSet ToDataSet<T>(IList<T> list)

        {

            return ToDataSet<T>(list, null);

        }


        /// <summary>
        /// 泛型集合转换DataSet
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <paramname="p_List">泛型集合</param>
        /// <paramname="p_PropertyName">待转换属性名数组</param>
        /// <returns></returns>
        /// 2008-08-01 22:44 HPDV2806
        public static DataSet ToDataSet<T>(IList<T> p_List, params string[] p_PropertyName)

        {

            List<string> propertyNameList = new List<string>();

            if (p_PropertyName != null)

                propertyNameList.AddRange(p_PropertyName);



            DataSet result = new DataSet();

            DataTable _DataTable = new DataTable();

            if (p_List.Count > 0)

            {

                PropertyInfo[] propertys = p_List[0].GetType().GetProperties();

                foreach (PropertyInfo pi in propertys)

                {

                    if (propertyNameList.Count == 0)

                    {

                        // 没有指定属性的情况下全部属性都要转换

                        _DataTable.Columns.Add(pi.Name, pi.PropertyType);

                    }

                    else

                    {

                        if (propertyNameList.Contains(pi.Name))

                            _DataTable.Columns.Add(pi.Name, pi.PropertyType);

                    }

                }



                for (int i = 0; i < p_List.Count; i++)

                {

                    ArrayList tempList = new ArrayList();

                    foreach (PropertyInfo pi in propertys)

                    {

                        if (propertyNameList.Count == 0)

                        {

                            object obj = pi.GetValue(p_List[i], null);

                            tempList.Add(obj);

                        }

                        else

                        {

                            if (propertyNameList.Contains(pi.Name))

                            {

                                object obj = pi.GetValue(p_List[i], null);

                                tempList.Add(obj);

                            }

                        }

                    }

                    object[] array = tempList.ToArray();

                    _DataTable.LoadDataRow(array, true);

                }

            }

            result.Tables.Add(_DataTable);

            return result;

        }



        /// <summary>
        /// DataSet装换为泛型集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <paramname="p_DataSet">DataSet</param>
        /// <paramname="p_TableIndex">待转换数据表索引</param>
        /// <returns></returns>
        /// 2008-08-01 22:46 HPDV2806
        public static IList<T> DataSetToIList<T>(DataSet p_DataSet, int p_TableIndex)

        {

            if (p_DataSet == null || p_DataSet.Tables.Count < 0)

                return null;

            if (p_TableIndex > p_DataSet.Tables.Count - 1)

                return null;

            if (p_TableIndex < 0)

                p_TableIndex = 0;



            DataTable p_Data = p_DataSet.Tables[p_TableIndex];

            // 返回值初始化

            IList<T> result = new List<T>();

            for (int j = 0; j < p_Data.Rows.Count; j++)

            {

                T _t = (T)Activator.CreateInstance(typeof(T));

                PropertyInfo[] propertys = _t.GetType().GetProperties();

                foreach (PropertyInfo pi in propertys)

                {

                    for (int i = 0; i < p_Data.Columns.Count; i++)

                    {

                        // 属性与字段名称一致的进行赋值

                        if (pi.Name.Equals(p_Data.Columns[i].ColumnName))

                        {

                            // 数据库NULL值单独处理

                            if (p_Data.Rows[j][i] != DBNull.Value)

                                pi.SetValue(_t, p_Data.Rows[j][i], null);

                            else

                                pi.SetValue(_t, null, null);

                            break;

                        }

                    }

                }

                result.Add(_t);

            }

            return result;

        }



        /// <summary>
        /// DataSet装换为泛型集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <paramname="p_DataSet">DataSet</param>
        /// <paramname="p_TableName">待转换数据表名称</param>
        /// <returns></returns>
        /// 2008-08-01 22:47 HPDV2806
        public static IList<T> DataSetToIList<T>(DataSet p_DataSet, string p_TableName)

        {

            int _TableIndex = 0;

            if (p_DataSet == null || p_DataSet.Tables.Count < 0)

                return null;

            if (string.IsNullOrEmpty(p_TableName))

                return null;

            for (int i = 0; i < p_DataSet.Tables.Count; i++)

            {

                // 获取Table名称在Tables集合中的索引值

                if (p_DataSet.Tables[i].TableName.Equals(p_TableName))

                {

                    _TableIndex = i;

                    break;

                }

            }

            return DataSetToIList<T>(p_DataSet, _TableIndex);

        }


        /// <summary>
        /// 返回List<Model>
        /// </summary>
        /// <typeparam name="T">Model类型</typeparam>
        /// <param name="entity">Model类型</param>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static List<T> PutAll<T>(T entity, DataSet ds) where T : new()
        {
            try
            {
                List<T> lists = new List<T>();
                if (ds.Tables[0].Rows.Count > 0)
                {
                    foreach (DataRow row in ds.Tables[0].Rows)
                    {
                        lists.Add(Put(new T(), row));
                    }
                }
                return lists;
            }
            catch (Exception)
            {
                //报错返回 null
                return null;
            }
        }

        /// <summary>
        /// 返回一条数据的Model
        /// </summary>
        /// <typeparam name="T">Model类型</typeparam>
        /// <param name="entity">Model类型</param>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static T PutOne_Model<T>(T entity, DataSet ds) where T : new()
        {
            try
            {
                T m = new T();
                if (ds.Tables[0].Rows.Count > 0)
                {
                    m = Put(new T(), ds.Tables[0].Rows[0]);
                }
                return m;
            }
            catch (Exception)
            {
                //报错返回 null
                return default(T);
                //throw;
            }
        }

        /// <summary>
        /// 处理数据行生成Model
        /// </summary>
        /// <typeparam name="T">Model类型</typeparam>
        /// <param name="entity">Model类型</param>
        /// <param name="row">数据行</param>
        /// <returns></returns>
        public static T Put<T>(T entity, DataRow row) where T : new()
        {
            //初始化 如果为null
            if (entity == null)
            {
                entity = new T();
            }
            //得到类型
            Type type = typeof(T);
            //取得属性集合
            PropertyInfo[] pi = type.GetProperties();
            foreach (PropertyInfo item in pi)
            {
                //判断数据中是否包含此列
                int index = row.Table.Columns.IndexOf(item.Name);
                if (index != -1)
                {
                    //给属性赋值
                    if (row[item.Name] != null && row[item.Name] != DBNull.Value)
                    {
                        if (item.PropertyType == typeof(System.DateTime))
                        {
                            //如果对日期格式有特殊要求 可以在这里转换
                            //日期要为空值 定义Model DateTime? 即可
                            item.SetValue(entity, Convert.ToDateTime(row[item.Name].ToString()), null);
                        }
                        else
                        {
                            //按Model原数据类型转换
                            item.SetValue(entity, Convert.ChangeType(row[item.Name], item.PropertyType), null);
                        }
                    }
                }
            }
            return entity;
        }

    }
}
